x86/ACPI: ignore processors which cannot be brought online
authorJan Beulich <jbeulich@suse.com>
Wed, 15 Sep 2021 09:00:40 +0000 (11:00 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 15 Sep 2021 09:00:40 +0000 (11:00 +0200)
ACPI 6.3 introduced a flag allowing to tell MADT entries describing
hotpluggable processors from ones which are simply placeholders (often
used by firmware writers to simplify handling there).

Inspired by a Linux patch by Mario Limonciello <mario.limonciello@amd.com>.

Requested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/acpi/boot.c
xen/include/acpi/actbl1.h

index 8fe2d6fe0f4267f661cc54514dfa69d5006e9ae8..5e38b4b17c19b63428d1287d2c150ea4d6006e66 100644 (file)
@@ -53,6 +53,8 @@ bool __initdata acpi_ioapic;
 static bool __initdata acpi_skip_timer_override;
 boolean_param("acpi_skip_timer_override", acpi_skip_timer_override);
 
+static uint8_t __initdata madt_revision;
+
 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 
 /* --------------------------------------------------------------------------
@@ -64,6 +66,8 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
        struct acpi_table_madt *madt =
                container_of(table, struct acpi_table_madt, header);
 
+       madt_revision = madt->header.revision;
+
        if (madt->address) {
                acpi_lapic_addr = (u64) madt->address;
 
@@ -86,6 +90,12 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
        if (BAD_MADT_ENTRY(processor, end))
                return -EINVAL;
 
+       /* Don't register processors that cannot be onlined. */
+       if (madt_revision >= 5 &&
+           !(processor->lapic_flags & ACPI_MADT_ENABLED) &&
+           !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE))
+               return 0;
+
        if ((processor->lapic_flags & ACPI_MADT_ENABLED) ||
            processor->local_apic_id != 0xffffffff || opt_cpu_info) {
                acpi_table_print_madt_entry(header);
@@ -136,6 +146,12 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
        if (BAD_MADT_ENTRY(processor, end))
                return -EINVAL;
 
+       /* Don't register processors that cannot be onlined. */
+       if (madt_revision >= 5 &&
+           !(processor->lapic_flags & ACPI_MADT_ENABLED) &&
+           !(processor->lapic_flags & ACPI_MADT_ONLINE_CAPABLE))
+               return 0;
+
        if ((processor->lapic_flags & ACPI_MADT_ENABLED) ||
            processor->id != 0xff || opt_cpu_info)
                acpi_table_print_madt_entry(header);
index e1991362dc61589bd2ef57f99b536f8d6d58f9d1..923641fc9e1caca452cde341bf8ab5ba92d42890 100644 (file)
@@ -858,7 +858,8 @@ struct acpi_madt_generic_translator {
 
 /* MADT Local APIC flags */
 
-#define ACPI_MADT_ENABLED           (1)        /* 00: Processor is usable if set */
+#define ACPI_MADT_ENABLED           (1 << 0)   /* 00: Processor is usable if set */
+#define ACPI_MADT_ONLINE_CAPABLE    (1 << 1)   /* 01: Processor can be onlined */
 
 /* MADT MPS INTI flags (inti_flags) */